package statistics;

import impsoft.scripting.ibot.enums.Skill;
import impsoft.utils.general.Timer;

import java.math.BigDecimal;

import base.DreamScript;

public class Experience {
	private Skill skill;
	private int startLevel;
	private int startExperience;
	private String previousTTL;
	private Timer updateExperiences = new Timer(500);
	private Timer timeRan = new Timer(0);
	private DreamScript script = null;

	public Experience(Skill skill) {
		super();
		this.skill = skill;
	}

	public Skill getSkill() {
		return skill;
	}

	public void startTracking(DreamScript script) throws InterruptedException {
		this.script = script;
		timeRan = script.getTimeRan();
		startLevel = script.theTabs.Statistics.getStatBottom(skill);
		startExperience = script.theTabs.Statistics.getStatExperience(skill);
		updateExperiences.reset();
		previousTTL = "00:00:00:";
	}

	public String getTTL(int level) throws InterruptedException {
		final StringBuilder tb = new StringBuilder();

		if (updateExperiences.isUp()) {
			updateExperiences.reset();
			final int diff = getXP() - startExperience;

			if (diff > 0) {
				final long runTime = (getCalculatedXP(level) - getXP()) * timeRan.getTimeElapsed() / diff;

				final Timer t = new Timer(runTime);
				tb.append(t.toStringTimeRemaining());
			}

			previousTTL = tb.toString();
		} else {
			return previousTTL;
		}

		return tb.toString();
	}

	public int getStartLevel() {
		return startLevel;
	}

	public String getTTL() throws InterruptedException {
		return getTTL(getLevel() + 1);
	}

	public int getLevel() throws InterruptedException {
		return script.theTabs.Statistics.getStatBottom(skill);
	}

	public double getPercentToLevel() throws InterruptedException {
		int xpTotal = getCalculatedXP(getLevel() + 1) - getCalculatedXP(getLevel());
		final int xpDone = getXP() - getCalculatedXP(getLevel());

		if (xpTotal == 0) {
			xpTotal = 1;
		}

		return round((double) 100 * xpDone / xpTotal, 2);
	}

	public double getPercentToLevel(int lvl) throws InterruptedException {
		int xpTotal = getCalculatedXP(lvl) - getCalculatedXP(getLevel());
		final int xpDone = getXP() - getCalculatedXP(getLevel());

		if (xpTotal == 0) {
			xpTotal = 1;
		}

		return round((double) 100 * xpDone / xpTotal, 2);
	}

	public static long getHourlyXP(long xp, Timer timeRan) {
		return xp * 60 * 60 / (timeRan.getTimeElapsed() / 1000 + 1);
	}

	public long getHourlyXP() throws InterruptedException {
		return getHourlyXP(getTotalXPGained(), timeRan);
	}

	public int getTotalXPGained() throws InterruptedException {
		return getXP() - startExperience;
	}

	public long getXPToLevel() throws InterruptedException {
		return getCalculatedXP(getLevel() + 1) - getXP();
	}

	public int getXP() throws InterruptedException {
		return script.theTabs.Statistics.getStatExperience(skill);
	}

	public int getCalculatedXP(int lvl) {
		int xp = 0;
		for (int i = 1; i < lvl; i++) {
			xp += Math.floor(i + 300 * Math.pow(2, i / 7.));
		}
		return (int) Math.floor(xp / 4);
	}

	public static double round(double d, int decimalPlace) {
		return new BigDecimal(Double.toString(d)).setScale(decimalPlace, BigDecimal.ROUND_HALF_UP).doubleValue();
	}
}
